<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        // 考点:
        // 1,循环
        // 2,闭包IIFE:使用闭包会使得数据都保存在内存中,使得内存消耗很大,不能滥用闭包.闭包可以读取局部变量
        // 3,计时器  setTimeout  setInterval
        // 4,var let:var可以重复声明,var定义的变量全局有效,var存在预解析/变量提升;let不能重复声明,定义的变量只在作用域内有效,不存在预解析/变量提升

        function Foo() {
            for(var i= 0;i<5;i++) {//var可以重复声明,所以5次循环的i是指向同一个内存地址的i
                setTimeout(function timer() {
                    console.log(i);
                }, 1000);
            }
            console.log(i);
        }
        Foo();//5 5 5 5 5 5    ===>   普通函数的调用,var定义的变量可以重复赋值,循环了5次,定时器也会有5个,计时器被放入了循环中,要等上下文代码执行后[循环结束后]才会执行定时器,而循环结束后i变为了5,因此输出6个5  [先执行的是循环体外部的console,最后才执行5个计时器 ]
    
        function Foo() {
            for(var i= 0;i<5;i++) {
                (function (i) {//闭包:可以读取局部变量,主要是可以让变量的值保存在内存中.

                    setTimeout(function timer() {
                        console.log(i);
                    }, 1000);

                })(i);
                
            }
            console.log(i);
        }
        Foo();//5 0 1 2 3 4   循环5次回生成5个定时器,IIFE声明函数的同时会立即调用函数一次,所以会形成一个私有作用域,所以变量i被独立了起来,每个定时器输出的i都不一样   [先执行的是循环体外部的console,最后才执行5个计时器 ]
    

        setTimeout(() => {
            console.log('1');
        },1000);
        console.log('2');
        setTimeout(() => {
            console.log('3');
        },0);
        // 2 3 1  定时器后执行,先执行上下文,所以先2,两个定时器一个等待0ms,1个等待1ms,所以先3 后1

        setTimeout(() => {
            console.log('1');
        },1000);
        const start = new Date();
        while (new Date() - start < 3000) {};//new Date()是实时时间戳,永远表示当前实时时间
        console.log('2');
        setTimeout(() => {
            console.log('3');
        },0);
        //2 1 3   定时器是在指定的一段时间之后执行,根据定时器的机制,不管它的这段时间是0还是多少,都会先去执行上下文的代码.
        //所以先执行while,再执行2,执行while后,其实时间已经过去3ms,第一个定时器已经结束定时了,所以再输出1,再3

    </script>
</body>
</html>